/**
 * 
 */
package gmu.drr.exercise;

import edu.uci.ics.jung.algorithms.filters.VertexPredicateFilter;
import edu.uci.ics.jung.graph.*;
import edu.uci.ics.jung.io.*;
import edu.uci.ics.jung.io.graphml.*;
import gmu.drr.entity.DomainVertexType;
import gmu.drr.entity.structure.*;

import java.io.*;
import java.util.Collection;

import org.apache.commons.collections15.*;

/**
 * @author RothmD01
 *
 */
public class BaseGraphMetricsTest {
	/**
	 * @author RothmD01
	 *
	 */
	class TransformerGraphFromMLMeta implements Transformer<GraphMetadata, DirectedSparseMultigraph<Vertex,Edge> > {

		@Override
		public DirectedSparseMultigraph<Vertex, Edge> transform(
				GraphMetadata arg0) {
			DirectedSparseMultigraph<Vertex, Edge> g;
			g = new DirectedSparseMultigraph<Vertex, Edge>();
			return g;
		}		
	}

	/**
	 * @author RothmD01
	 *
	 */
	class TransformerHyperEdgeFromMLMeta implements Transformer<HyperEdgeMetadata, Edge> {

		@Override
		public Edge transform(
				HyperEdgeMetadata arg0) {
			Edge e;
			e = new Edge();
			// TODO fill in data from the edge metadata
			return e;
		}		
	}

	public static final String fname = "testGraphOut.txt";
	
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Graph<Vertex, Edge> g;
		// TODO Auto-generated method stub
		BaseGraphMetricsTest foo = new BaseGraphMetricsTest();
		g = foo.doIORead();
		foo.executeMetrics(g);
	}
	
	public Graph<Vertex,Edge> doIORead() {
		Graph<Vertex, Edge> graph = new DirectedSparseMultigraph<Vertex, Edge>();	
		FileReader fRead = null;
		
		try {
			fRead = new FileReader( fname) ;
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		GraphMLReader2<DirectedSparseMultigraph<Vertex, Edge>, Vertex, Edge> graphRd = null;
		graphRd = new GraphMLReader2<DirectedSparseMultigraph<Vertex, Edge>, Vertex, Edge>(
				fRead ,
                new TransformerGraphFromMLMeta(),
                Vertex.getTransformerFromMLMeta(),
                Edge.getTransformerEdgeFromMLMeta(),
                new TransformerHyperEdgeFromMLMeta() );		

		try {
			graph = graphRd.readGraph();
		} catch (GraphIOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return graph;
	}
	
	public void dumpStats( Graph<Vertex, Edge> graph) {
		final int orderHistBuckets=10;
		int n, e;
		n = graph.getVertexCount();
		e = graph.getEdgeCount();

		System.out.println( "TOTAL vertics: "+n);
		System.out.println( "TOTAL edges: "+e);
		
		int outO[] = new int[orderHistBuckets], 
			inO[] = new int[orderHistBuckets], 
			degO[] = new int[orderHistBuckets];
		Collection<Vertex> verts = graph.getVertices();
		for( Vertex v : verts ) {
			int iO, oO, dO;
			iO = graph.inDegree(v);
			oO = graph.outDegree(v);
			dO = graph.degree(v);
			if( iO > 9 ) iO = 9;
			if( oO > 9 ) oO = 9;
			if( dO > 9 ) dO = 9;
			outO[oO] += 1;
			inO[iO] += 1;
			degO[dO] += 1;
		}
		System.out.println( "In Order Hist:");
		for( int i = 0; i < orderHistBuckets; i++ ) {
			System.out.println( i +" : "+inO[i]);
		}
		System.out.println( "Out Order Hist:");
		for( int i = 0; i < orderHistBuckets; i++ ) {
			System.out.println( i +" : "+outO[i]);
		}
		System.out.println( "Deg Order Hist:");
		for( int i = 0; i < orderHistBuckets; i++ ) {
			System.out.println( i +" : "+degO[i]);
		}

	}
	
	public void executeMetrics( Graph<Vertex,Edge> graph ) {
		dumpStats(graph);
		
		VertexPredicateFilter<Vertex, Edge> consSocial, itemSocial, pref;
		consSocial = new VertexPredicateFilter<Vertex, Edge>(
				new Predicate<Vertex>() {
					public boolean evaluate(Vertex v) {
						if (v.domainType == DomainVertexType.CONS)
							return true;
						return false;
					}
				});
		Graph<Vertex, Edge> g2;
		g2 = consSocial.transform(graph);
		
		dumpStats(g2);
	}

}

